package com.mioto.ld.communication.mqtt.protocol;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.mioto.ld.communication.DeviceFunctionLogProcess;
import com.mioto.ld.communication.mqtt.protocol.cache.DeviceInfoCache;
import com.mioto.ld.module.device.model.Device;
import com.mioto.ld.module.device.service.IDeviceService;
import com.mioto.ld.module.device.service.impl.DeviceServiceImpl;
import com.mioto.ld.module.product.model.Product;
import com.mioto.ld.module.product.service.IProductService;
import com.mioto.ld.communication.mqtt.protocol.model.Message;
import com.mioto.ld.communication.mqtt.protocol.model.device.DeviceAuthPayload;
import com.mioto.ld.utils.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.concurrent.Executor;

/**
 * @author mioto-qinxj
 * @date 2024/5/8
 * @desc 认证处理
 */
@Slf4j
public class AuthHandleStrategy implements IReceiptHandleStrategy {

    private IDeviceService deviceService;
    private DeviceInfoCache deviceInfoCache;

    private IProductService productService;

    private DeviceFunctionLogProcess deviceFunctionLogProcess;


    public AuthHandleStrategy(){
        deviceService = SpringBeanUtil.getBean(DeviceServiceImpl.class);
        deviceInfoCache = SpringBeanUtil.getBean(DeviceInfoCache.class);
        productService = SpringBeanUtil.getBean(IProductService.class);
        deviceFunctionLogProcess = SpringBeanUtil.getBean(DeviceFunctionLogProcess.class);
    }

    @Override
    public void protocolHandler(Message message) throws Exception{
        log.info("---------------------设备 - {} 认证消息处理开始---------------------",message.getSn());
        try {
            Date now = new Date();
            boolean saveResult = saveDeviceInfo(message,now);
            if (saveResult){
                updateOnLineTimeAndSaveLog(message,now);
            }
        } catch (Exception e) {
            throw new RuntimeException("设备认证失败",e);
        }
        log.info("---------------------设备 - {} 认证消息处理结束---------------------",message.getSn());
    }

    /**
     * 关联产品，并保存设备信息
     * @param message
     */
    private boolean saveDeviceInfo(Message message,Date now) throws Exception{
        int result = 1;
        Device device = deviceInfoCache.get(message.getSn());
        DeviceAuthPayload payload = (DeviceAuthPayload) message.getMessageBody().getPayload();
        if (ObjectUtil.isNull(device)){
            Product product = productService.findByColumn("model",payload.getModel());
            if (ObjectUtil.isNull(product)) {
                log.warn("未找到设备型号 - {} 对应的产品信息!",payload.getModel());
                result = 0;
            }else {
                log.info("未发现设备 - {},保存设备信息,关联产品 - {}", message.getSn(), product.getName());
                device = new Device();
                device.setProductId(product.getId());
                device.setSn(message.getSn());
                device.setManufacturer(payload.getManufacturer());
                device.setFirmwareVersion(payload.getFirmwareVersion());
                device.setDeliveryTime(DateUtil.date(payload.getFactoryDate()));
                device.setRegistrationTime(now);
                device.setLastOpenDate(now);
                result = deviceService.insert(device);
                deviceInfoCache.put(device);
            }
        }
        return result > 0;
    }

    /**
     * 修改设备开机时间,并更新开机日志
     * @param message
     * @param now
     */
    public void updateOnLineTimeAndSaveLog(Message message,Date now){
        log.info("设备 - {} 已经存在,更新设备最后开机时间",message.getSn());
        deviceService.updateLineDateBySn(message.getSn(),now,null);
        log.info("保存设备 - {} 开机日志",message.getSn());
        deviceFunctionLogProcess.saveFunctionLog(message.getSn(),message.getMtype(),now);
    }
}
